#region Copyright
/// <copyright>
/// Copyright (c) 2007 Ilia Shramko.
/// Released under the terms of the GNU General Public License.
/// </copyright>
#endregion

using System;
using System.Collections.Generic;
using System.Text;

namespace Osh.Teletext
{
	public class PacketX26 : EnhancementDataPacket
	{
		private enum RowMode
		{
			FullScreenColour = 0,
			FullRowColour = 1,
			SetActivePosition = 4,
			AddressDisplayRow0 = 7,
			TerminationMarker = 0x1F,
		}

		private enum ColumnMode
		{
			ForegroundColour = 0,
			/// <summary>
			/// Block Mosaic Character from the G1 Set
			/// </summary>
			G1Char = 1,
			/// <summary>
			/// Line Drawing or Smoothed Mosaic Character from the G3 Set at Level 1.5
			/// </summary>
			G3Char1 = 2,
			BackgroundColour = 3,
			/// <summary>
			/// Modified G0 and G2 Character Set Designation
			/// </summary>
			ModifiedCharsetDesignation = 8,
			/// <summary>
			/// Character from the G0 Set at Levels 2.5 and 3.5
			/// </summary>
			G0Char = 9,
			/// <summary>
			/// Line Drawing and Smoothed Mosaic Character from the G3 Set at Levels 2.5 and 3.5
			/// </summary>
			G3Char2 = 0xB,
			DisplayAttributes = 0xC,
			/// <summary>
			/// Character from the G2 Supplementary Set
			/// </summary>
			G2Char = 0xF,
			/// <summary>
			/// G0 character with diacritical mark. First mode value.
			/// </summary>
			G0CharWithDiacriticMarkFirst = 0x10,
			/// <summary>
			/// G0 character with diacritical mark. Last mode value.
			/// </summary>
			G0CharWithDiacriticMarkLast = 0x1F,
		}

		public List<CharReplacement> _charReplacements;

		public PacketX26(int magazine, int packet, byte[] data, int position)
			: base(magazine, packet, data, position)
		{
			_charReplacements = new List<CharReplacement>();

			CharPosition activePosition = CharPosition.TopLeft;
			Charset activeCharset = Charset.Empty;
			for(int i = 0; i < EnhancementDataPacket.MaxTripletNumber; i++)
			{
				int triplet = this.GetTriplet(i);
				int address = triplet & 0x3F;
				int mode = (triplet >> 6) & 0x1F;
				byte dataByte = (byte)((triplet >> 11) & 0x7F);
				
				if(address < 40) // column address
				{
					ColumnMode columnMode = (ColumnMode)mode;
					if(columnMode == ColumnMode.G1Char)
					{
						activePosition.Column = address;
						_charReplacements.Add(new CharReplacement(activePosition, Charset.G1, dataByte));
					}
					else if(columnMode == ColumnMode.G3Char1)
					{
						activePosition.Column = address;
						_charReplacements.Add(new CharReplacement(activePosition, Charset.G3, dataByte));
					}
					else if(columnMode == ColumnMode.ModifiedCharsetDesignation)
					{
						activeCharset = new Charset(dataByte);
					}
					else if(columnMode == ColumnMode.G0Char)
					{
						activePosition.Column = address;
						_charReplacements.Add(new CharReplacement(activePosition,
							activeCharset != Charset.Empty ? activeCharset : Charset.G0, dataByte));
					}
					else if(columnMode == ColumnMode.G3Char2)
					{
						activePosition.Column = address;
						_charReplacements.Add(new CharReplacement(activePosition, Charset.G3, dataByte));
					}
					else if(columnMode == ColumnMode.G2Char)
					{
						activePosition.Column = address;
						_charReplacements.Add(new CharReplacement(activePosition,
							activeCharset != Charset.Empty ? activeCharset : Charset.G2, dataByte));
					}
					else if((int)columnMode >= (int)ColumnMode.G0CharWithDiacriticMarkFirst &&
						(int)columnMode <= (int)ColumnMode.G0CharWithDiacriticMarkLast)
					{
						activePosition.Column = address;
						int diacriticMark = (int)columnMode - (int)ColumnMode.G0CharWithDiacriticMarkFirst;
						_charReplacements.Add(new CharReplacement(activePosition, dataByte, (byte)diacriticMark));
					}
					else
					{
						//address = address;
					}
				}
				else // row adress 40-63 = 24,1-23
				{
					int addressRow = address == 40 ? 24 : address - 40;

					RowMode rowMode = (RowMode)mode;
					if(rowMode == RowMode.AddressDisplayRow0)
					{
						if(address == 0x3F) // 111111
						{
							activePosition = CharPosition.TopLeft;
							// colore parsing skipped
						}
					}
					else if(rowMode == RowMode.FullRowColour)
					{
						activePosition.Row = addressRow;
						activePosition.Column = 0;
					}
					else if(rowMode == RowMode.SetActivePosition)
					{
						activePosition.Row = addressRow;
						if(dataByte < 40)
							activePosition.Column = dataByte;
					}
					else if(rowMode == RowMode.TerminationMarker)
					{
						if(address == 0x3F && dataByte == 0x1F)
							break;
					}
					else
					{
						//addressRow = addressRow;
					}
				}
			}

		}

		public List<CharReplacement> CharReplacements
		{
			get { return _charReplacements; }
		}

	}
}
